Skip to content

fix: add JsCommands schema stub in openrpc-dapp-api.json#1726

Open
alleneubank wants to merge 2 commits into
canton-network:mainfrom
alleneubank:bb/jscommands-schema-stub-fix
Open

fix: add JsCommands schema stub in openrpc-dapp-api.json#1726
alleneubank wants to merge 2 commits into
canton-network:mainfrom
alleneubank:bb/jscommands-schema-stub-fix

Conversation

@alleneubank
Copy link
Copy Markdown

@alleneubank alleneubank commented May 9, 2026

Summary

Replaces the JsCommands placeholder in api-specs/openrpc-dapp-api.json with a properly-typed schema. Single commit (5c24ca75), api-specs/openrpc-dapp-api.json only.

This is the upstream candidate for canton-network/wallet-gateway (renamed from hyperledger-labs/splice-wallet-kernel). Opening on the private fork first for structured review before upstreaming.

Why

The components.schemas.JsCommands entry has been a placeholder since #40 ("Api spec placeholders", 2025-06-05):

"JsCommands": {
  "title": "JsCommands",
  "type": "object",
  "description": "Structure representing JS commands for transaction execution",
  "additionalProperties": true
}

Verified still in this state on canton-network/wallet-gateway:main (bd545745).

// =====================================================================
// Pre-fix: the published OpenRPC stub
//   "JsCommands": { "type": "object", "additionalProperties": true }
// → openapi-codeg...

Playground Link

This stub contradicts four other parts of this same repo:

  1. Canton Ledger APIapi-specs/ledger-api/3.4.12/openapi.yaml (and 3.5.1) define JsCommands.commands as a required, non-empty type: array whose items are $ref: Command.
  2. SDK docsdocs/dapp-building/dapp-sdk/usage.md:205 shows { commands: [ { CreateCommand: {...} } ] }.
  3. Canonical exampleexamples/ping/src/commands/createPingCommand.ts:9 builds commands: [ { CreateCommand: {...} } ].
  4. Upstream runtimewallet-gateway/remote/src/dapp-api/controller.ts:243 accesses params.commands?.[0], only valid if commands is an array.

PRs #904, #1259, #1339, and #1609 all touched JsPrepareSubmissionRequest without filling this in.

What changes

  • Four named variant schemas (CreateCommand, ExerciseCommand, CreateAndExerciseCommand, ExerciseByKeyCommand), each a one-key tagged object. Inner shapes left opaque (additionalProperties: true) — the description defers to the Canton Ledger API to avoid drift.
  • A Command oneOf tagged-union referencing the four variants.
  • JsCommands redefined as array of Command, minItems: 1.

The oneOf discriminated-union path is what generated clients need to emit a clean z.union([...]) with openapi-zod-client (the default json-schema-to-zod path produces a superRefine fallback otherwise).

Naming note (not a bug)

The dApp API uses JsCommands as the inner array (array<Command>), with the wrapper object being JsPrepareSubmissionRequest = {commandId, commands: $ref JsCommands, actAs, ...}. The Ledger API uses the same name JsCommands for the outer wrapper {commandId, commands: array<Command>, actAs, ...}. Same logical content, different nesting level. Our patch preserves the existing dApp-API structure (matches JsPrepareSubmissionRequest's pre-existing reference of commands: $ref JsCommands), so this is consistent — not introduced by this PR. Worth verifying in review.

Severity

Blocks CIP-0103 interop for any wallet that generates its JSON-RPC validators from the published OpenRPC spec.

Downstream verification

Verified via Send Canton Wallet webext, with a CIP-0103 conformance Playwright spec driving the upstream examples/ping dApp against a patched wallet.

Base

Rebased onto canton-network/wallet-gateway:main (bd545745). Fork's main synced from old hyperledger-labs/splice-wallet-kernel (62 commits behind canonical) to current canton-network/wallet-gateway tip on 2026-05-08.

Review focus

  • Coverage: Are there other Daml command variants in the Ledger API (or planned) that this 4-variant union misses?
  • Fidelity: Do our oneOf shapes match what wallet-gateway/remote/src/dapp-api/controller.ts actually accepts at runtime?
  • Generation: Verify openapi-zod-client emits clean z.union([z.object({CreateCommand: ...}), ...]) from this oneOf, not a superRefine fallback.
  • Naming: Is the JsCommands array-vs-wrapper-object naming inconsistency between dApp API and Ledger API a deliberate layering choice or worth raising upstream?

The components.schemas.JsCommands entry is still the placeholder
introduced in canton-network#40 ("Api spec placeholders", 2025-06-05):

    "JsCommands": {
      "title": "JsCommands",
      "type": "object",
      "description": "Structure representing JS commands for transaction execution",
      "additionalProperties": true
    }

This stub has never been filled in, even though PRs canton-network#904, canton-network#1259, canton-network#1339,
and canton-network#1609 have all touched JsPrepareSubmissionRequest. It contradicts
four other parts of this same repo:

1. Canton Ledger API — api-specs/ledger-api/3.4.12/openapi.yaml
   lines 4736-4751 define JsCommands.commands as a required, non-empty
   type: array whose items are $ref Command.
2. SDK docs — docs/dapp-building/dapp-sdk/usage.md:205 shows
   { commands: [ { CreateCommand: {...} } ] }.
3. Canonical example — examples/ping/src/commands/createPingCommand.ts:9
   builds commands: [ { CreateCommand: {...} } ].
4. Upstream runtime — wallet-gateway/remote/src/dapp-api/controller.ts:243
   accesses params.commands?.[0], only valid if commands is an array.

This patch replaces the stub with:

- Four named variant schemas (CreateCommand, ExerciseCommand,
  CreateAndExerciseCommand, ExerciseByKeyCommand), each a one-key object
  with opaque inner shape (additionalProperties: true, description
  defers to Canton Ledger API).
- A Command oneOf tagged-union referencing the four variants.
- JsCommands redefined as an array of Command, minItems: 1.

The oneOf discriminated union path is what generated clients need to
emit a clean z.union([...]) with openapi-zod-client (rather than the
superRefine fallback the default json-schema-to-zod path produces).

Severity: blocks CIP-0103 interop for any wallet that generates its
JSON-RPC validators from the published OpenRPC spec. Downstream fix
verified in 0xsend/canton-monorepo#2810 (Send Canton Wallet webext),
with a CIP-0103 conformance Playwright spec driving the upstream
examples/ping dApp against a patched wallet.

Staging fork: 0xsend/wallet-gateway (private, for pre-upstream
review). This commit targets the detached pin f30e464 to match the
canton-monorepo work-dir reference.

Sealed-by-rl-review: a3261c182921581712ca124f0018bfcd45c04f48 (diff-range, 6 commits)
Signed-off-by: Allen <allen@send.it>

--- Squashed commits ---
5c24ca75 Fix JsCommands schema stub in openrpc-dapp-api.json
dcf81def fix(review-fix-up): address major-1 schema titles
513ce47c fix(review-fix-up): address major-2 generated commands
dbf68f5d fix(review-fix-up): address major-1: refresh dapp clients
a1dcb80d fix(review-fix-up): address major-1: sync dapp openrpc schemas
a3261c18 fix(review-fix-up): address major-2: accept command arrays
@alleneubank alleneubank requested review from a team as code owners May 9, 2026 21:53
@mjuchli-da mjuchli-da self-assigned this May 10, 2026
@mjuchli-da mjuchli-da changed the title Fix JsCommands schema stub in openrpc-dapp-api.json fix: JsCommands schema stub in openrpc-dapp-api.json May 18, 2026
Copy link
Copy Markdown
Contributor

@mjuchli-da mjuchli-da left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delayed review:
I generally support defining the schema more specifically, and in the case of JsCommands, it is well worth it, given that the type is technically defined over in the OpenApi specification of the ledger api.

I want to ensure this does not block other CIP-compliant wallets, including Wallet Connect, for now (it shouldn't). @alexmatson-da will check and do the final approval.

@alexmatson-da alexmatson-da changed the title fix: JsCommands schema stub in openrpc-dapp-api.json fix: add JsCommands schema stub in openrpc-dapp-api.json May 18, 2026
Copy link
Copy Markdown
Contributor

@alexmatson-da alexmatson-da left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants